namespace OneWorks.Utils.FluentData
{
    using System;
    using System.Collections.Generic;

    internal abstract class BaseStoredProcedureBuilder
    {
        public BuilderData Data { get; set; }
        protected ActionsHandler Actions { get; set; }

        public BaseStoredProcedureBuilder(IDbCommand command, string name)
        {
            this.Data = new BuilderData(command, name);
            this.Actions = new ActionsHandler(this.Data);
        }

        private IDbCommand GetPreparedDbCommand()
        {
            this.Data.Command.CommandType(DbCommandTypes.StoredProcedure);
            this.Data.Command.ClearSql.Sql(this.Data.Command.Data.Context.Data.Provider.GetSqlForStoredProcedureBuilder(this.Data));
            return this.Data.Command;
        }

        public void Dispose()
        {
            this.Data.Command.Dispose();
        }

        public TParameterType ParameterValue<TParameterType>(string outputParameterName)
        {
            return this.Data.Command.ParameterValue<TParameterType>(outputParameterName);
        }

        public int Execute()
        {
            return this.GetPreparedDbCommand().Execute();
        }

        public List<TEntity> QueryMany<TEntity>(Action<TEntity, IDataReader> customMapper = null)
        {
            return this.GetPreparedDbCommand().QueryMany<TEntity>(customMapper);
        }

        public List<TEntity> QueryMany<TEntity>(Action<TEntity, dynamic> customMapper)
        {
            return this.GetPreparedDbCommand().QueryMany<TEntity>(customMapper);
        }

        public TList QueryMany<TEntity, TList>(Action<TEntity, IDataReader> customMapper = null) where TList : IList<TEntity>
        {
            return this.GetPreparedDbCommand().QueryMany<TEntity, TList>(customMapper);
        }

        public TList QueryMany<TEntity, TList>(Action<TEntity, dynamic> customMapper) where TList : IList<TEntity>
        {
            return this.GetPreparedDbCommand().QueryMany<TEntity, TList>(customMapper);
        }

        public void QueryComplexMany<TEntity>(IList<TEntity> list, Action<IList<TEntity>, IDataReader> customMapper)
        {
            this.GetPreparedDbCommand().QueryComplexMany<TEntity>(list, customMapper);
        }

        public void QueryComplexMany<TEntity>(IList<TEntity> list, Action<IList<TEntity>, dynamic> customMapper)
        {
            this.GetPreparedDbCommand().QueryComplexMany<TEntity>(list, customMapper);
        }

        public TEntity QuerySingle<TEntity>(Action<TEntity, IDataReader> customMapper = null)
        {
            return this.GetPreparedDbCommand().QuerySingle<TEntity>(customMapper);
        }

        public TEntity QuerySingle<TEntity>(Action<TEntity, dynamic> customMapper)
        {
            return this.GetPreparedDbCommand().QuerySingle<TEntity>(customMapper);
        }

        public TEntity QueryComplexSingle<TEntity>(Func<IDataReader, TEntity> customMapper)
        {
            return this.GetPreparedDbCommand().QueryComplexSingle(customMapper);
        }

        public TEntity QueryComplexSingle<TEntity>(Func<dynamic, TEntity> customMapper)
        {
            return this.GetPreparedDbCommand().QueryComplexSingle(customMapper);
        }
    }
}